// 引入定义仓库的函数
import { defineStore } from 'pinia';
// 引入操作 token 的函数
import { getToken, removeToken, setToken } from '../utils/token-utils';
// 登录后响应获取的用户信息的接口类型
import type { UserInfoState } from './interface';
// 引入消息框组件
import {ElMessage} from 'element-plus'
// 引入静态/动态/任意路由
import {staticRoutes, allAsyncRoutes, anyRoute} from '@/router/routes'
// 引入登录相关的接口函数
import {loginApi, logoutApi, getUserInfoApi} from '@/api/acl/login'
// 引入路由对象
import router from '@/router'
// 引入路由相关类型
import type {RouteRecordRaw} from 'vue-router'
// 引入深拷贝
import {cloneDeep} from 'lodash'

// 过滤动态路由
function filterRoutes(asyncRoutes: RouteRecordRaw[], routeNames: string[]) {
  return asyncRoutes.filter(route => {
    // 判断路由名称数组里是否包含路由信息对象的名字
    if (routeNames.indexOf(route.name as string) === -1) return false
    // 判断是否有子路由
    if (route.children && route.children.length > 0) {
      // 递归过滤
      route.children = filterRoutes(route.children, routeNames)
    }
    return true
  })
}
// 通过路由器注册路由
function addRoutes(routes: RouteRecordRaw[]) {
  routes.forEach(route => router.addRoute(route))
}
// 重置路由
function resetRouter() {
  const routes = router.getRoutes() // 获取所有路由对象的数组
  // 通过路由器移除所有路由
  routes.forEach(route => {
    // 根据路由的name属性移除
    route.name && router.removeRoute(route.name)
  })
  // 重新注册静态路由
  addRoutes(staticRoutes)
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {

	state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    menuRoutes: [], //路由相关信息
    roles: [], // 角色名称的数组
    authBtnList: [] // 按钮标识数组
  }),

	actions: {
    // 登录
    async login (username: string, password: string) {
      // 调用请求接口函数 获取token
      const {token} = await loginApi(username, password)
      // 存储至仓库 token
      this.token = token
      // 本地存储
      setToken(token)
    },
    // 携带token获取用户信息对象
    async getInfo () {
      const result = await getUserInfoApi()
      // 更新数据
      this.name = result.name
      this.avatar = result.avatar
      this.roles = result.roles
      this.authBtnList = result.buttons
      // 更新菜单显示的路由对象数组
      this.setRoutes(result.routes)
    },

    setRoutes(routeNames: string[]) {
      // 过滤动态路由
      const asyncRoutes = filterRoutes(cloneDeep(allAsyncRoutes), routeNames)
      // 路由注册
      addRoutes([...asyncRoutes, anyRoute])
      // 设置菜单显示的路由数组 
      this.menuRoutes = [...staticRoutes , ...asyncRoutes]
    },

    // 重置用户信息 即登出
    async reset () {
      // 判断是否是登录状态
      this.name && await logoutApi()
      // 移除缓存中 token
      removeToken()
      // 重置仓库数据
      this.token = ''
      this.name = ''
      this.avatar = ''
      this.menuRoutes = []
      this.authBtnList = []
      this.roles = []
      // 重置路由
      resetRouter()
    }
	},
});
